﻿// ============================================================================
//  _ __   ___  ___  ___ _ __ ___  _   _
// | '_ \ / _ \/ __|/ _ \ '_ ` _ \| | | |
// | | | |  __/\__ \  __/ | | | | | |_| |
// |_| |_|\___||___/\___|_| |_| |_|\__,_|
//
// NES Emulator by daxnet, 2024
// MIT License
// ============================================================================

using System.Reflection;
using NesEmu.Console.Models;
using NesEmu.Core;

namespace NesEmu.Console;

public partial class FrmControllerSettings : Form
{

    #region Public Constructors

    public FrmControllerSettings(ConsoleSettings settings)
        : this()
    {
        LoadControllerButtons(settings.Controllers?[0] ?? ControllerSetting.Default);
        controllerSettingControl.ControllerKeysPressed += ControllerSettingControlOnControllerKeysPressed;
    }

    #endregion Public Constructors

    #region Private Constructors

    private FrmControllerSettings()
    {
        InitializeComponent();
    }

    #endregion Private Constructors

    #region Public Properties

    public ControllerSetting Setting
    {
        get
        {
            var result = new ControllerSetting { Name = ControllerSetting.Default.Name };
            foreach (ListViewItem item in lv.Items)
            {
                typeof(ControllerSetting)
                    .GetProperty(item.Text, BindingFlags.Public | BindingFlags.Instance)
                    ?.SetValue(result, item.SubItems[1].Text);
            }

            return result;
        }
    }

    #endregion Public Properties

    #region Private Methods

    private void btnReset_Click(object sender, EventArgs e)
    {
        LoadControllerButtons(ControllerSetting.Default);
    }

    private void ControllerSettingControlOnControllerKeysPressed(object? sender,
        ControllerSettingControl.ControllerKeysPressedEventArgs e)
    {
        if (lv.SelectedIndices.Count > 0)
        {
            var selectedIdx = lv.SelectedIndices[0];
            var lvi = lv.Items[selectedIdx];
            lvi.SubItems[1].Text = e.PressedKeys[0];
            lvi.Selected = false;
            if (selectedIdx < lv.Items.Count - 1)
            {
                lv.Items[selectedIdx + 1].Selected = true;
            }
        }
    }

    private void LoadControllerButtons(ControllerSetting controllerSetting)
    {
        lv.Items.Clear();
        var controllerButtonNames = Enum.GetNames(typeof(Controller.Buttons));
        foreach (var buttonName in controllerButtonNames)
        {
            var lvi = lv.Items.Add(buttonName);
            var mappedKeyName = typeof(ControllerSetting)
                                    .GetProperty(buttonName, BindingFlags.Public | BindingFlags.Instance)
                                    ?.GetValue(controllerSetting)
                                ??
                                string.Empty;
            lvi.SubItems.Add(mappedKeyName.ToString());
        }

        lv.Items[0].Selected = true;
    }

    private void lv_KeyDown(object sender, KeyEventArgs e)
    {
        e.SuppressKeyPress = true;
    }

    #endregion Private Methods

}